using System;
using System.Collections.Generic;
using System.Text;
using SharpObjects.Configuration;
using SharpObjects.Configuration.ConfigurationProviders;
using SharpObjects.Instantiation;
using SharpObjects.Interfaces;
using SharpObjects.PathMapping;

namespace SharpObjects.Data
{
    // USAGE
/*    
            XmlConfig config = new XmlConfig("Factory.config");

            SqlStatementFactory factory = config.GetObject<SqlStatementFactory>("//configuration/sql_statements_factory");
            SqlStatement stat1 = factory.GetStatement("insert_folder_tree");
*/
    // CONFIG FILES
    /*
        <?xml version="1.0" encoding="utf-8" ?>
        <!-- SQL STATEMENTS CONFIG -->
        <configuration>

          <sql_statements>
            <statement id="insert_folder_tree">
              <sql>
                insert into folder_tree (id, parentid, childid, datemodified, modifiedby, datecreated, createdby )
                values ({0}, {1}, {2}, {3}, {4}, {5}, {6})
              </sql>
              <parameters>id, parentid, childid, datemodified, modifiedby, datecreated, createdby </parameters>
            </statement>
            <statement id="insert_items">
              <sql>
                insert into items (itemid, description )
                values ({0}, {1})
              </sql>
              <parameters>itemid, description </parameters>
            </statement>
          </sql_statements>
        </configuration>

        <?xml version="1.0" encoding="utf-8" ?>
        <!-- FACTORY CONFIG -->
        <configuration>

          <sql_statements_factory assembly="SharpObjects.Data.dll" class="SharpObjects.Data.SqlStatementFactory">
            <statement_assembly>SharpObjects.Data.dll</statement_assembly>
            <statement_class>SharpObjects.Data.SqlStatement</statement_class>
            <sql_statements_file>SqlStatements.config</sql_statements_file>
          </sql_statements_factory>
 
        </configuration>
    */

    public class SqlStatementFactory : IXmlInitializable 
    {
        public bool IsInitialized { get; set; }

        private IConfigurationProvider config = null;
        private string assemblyPath = null;
        private string typeName = null;

        public SqlStatementFactory()
        {
        }

        public SqlStatementFactory(IConfigurationProvider config, string assemblyName, string className)
        {
            this.config = config;
        }

        public SqlStatement GetStatement(string statementId)
        {
            string xPath = string.Format("//sql_statements/statement[@id='{0}']", statementId);
            ITypeDescriptor typeDescriptor = new TypeDescriptor(this.assemblyPath, this.typeName);
            SqlStatement statement = this.config.GetObject<SqlStatement>(xPath, typeDescriptor);
            return statement;
        }


        #region IXmlInitializable Members

        /*
          <sql_statements_factory assembly="ARD.Data.dll" class="ARD.Data.SqlStatementFactory">
            <statement_assembly>SqlResource.exe</statement_assembly>
            <statement_class>ARD.Data.SqlStatement</statement_class>
            <sql_statements_file>SqlStatements.config</sql_statements_file>
          </sql_statements_factory>
        */
        public void Initialize(System.Xml.XmlElement initializationXmlElement)
        {
            IConfigurationProvider init = new XmlConfigurationProvider(initializationXmlElement);
            this.assemblyPath = init.GetString("statement_assembly");
            this.typeName = init.GetString("statement_class");
            string statementFile = init.GetString("sql_statements_file", (string)null);

            if (statementFile != null)
            {
                this.config = new XmlConfigurationProvider(statementFile, PathMapperFactory.PathMapper);
            }
            else
            {
                this.config = new XmlConfigurationProvider(initializationXmlElement.OwnerDocument.DocumentElement);
            }

            this.IsInitialized = true;
        }

        #endregion
    }
}
